/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.jndi;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Collections;
import javax.naming.CompositeName;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.naming.NameClassPair;
import javax.naming.Context;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.netbeans.modules.jndi.utils.APCTarget;
/** Children class for Directories in JNDI tree.
* It's responsible for lazy initialization as well
* as it is an data model for JndiNode.
*
* @author Ales Novak, Tomas Zezula
*/
public final class JndiChildren extends Children.Keys implements APCTarget {
/** This constant represents the name of context class */
public final static String CONTEXT_CLASS_NAME = "javax.naming.Context";
/** Class object for javax.naming.Context */
private static Class ctxClass;
/** Initial Directory context */
private final Context parentContext;
/** Offset in Initial Directory context */
private final CompositeName offset;
/** The shadow key list for merginag and handling errors*/
private ArrayList keys;
/** Constructor
* @param parentContext the initial context
* @param offset the relative offset of Node in context
*/
public JndiChildren(Context parentContext, CompositeName offset){
this.parentContext = parentContext;
this.offset = offset;
this.keys = new ArrayList();
}
/** Called when node is being opened
*/
protected void addNotify(){
//Construct WaitNode key
JndiKey waitKey = new JndiKey();
setKeys (new Object[]{waitKey});
prepareKeys();
}
/** Called when node is not being used any more
*/
protected void removeNotify(){
setKeys (Collections.EMPTY_SET);
}
/** Returns actual offset
* @return the relative offset of Node
*/
public CompositeName getOffset() {
return offset;
}
/** Returns context
* @return the initial context
*/
public Context getContext() {
return parentContext;
}
/** This method creates keys
* exception NamingException if Context.list() failed
*/
public void prepareKeys(){
JndiRootNode.getDefault().refresher.addNewItem(this);
}
/** Creates Node for key
* @param key the key for which the Node should be created
* @return the array of created Nodes
*/
public Node[] createNodes(Object key) {
NameClassPair np = null;
String objName = null;
CompositeName newName = null;
if (key == null) {
return null;
}
if (! (key instanceof JndiKey)) {
return null;
}
if (((JndiKey)key).wait){
// Temporary Wait Node
// This Node has no data part, has to be handled here
return new Node[]{new WaitNode()};
}
try{
np = ((JndiKey)key).name;
objName = np.getName();
newName = (CompositeName) ((CompositeName) offset.clone()).add(objName);
if (((JndiKey)key).failed){
// Failed Node
return new Node[] {new JndiFailedNode(key, parentContext, newName, objName, np.getClassName())};
}
else if (isContext(np.getClassName())) {
// Contex Node
return new Node[] {new JndiNode(key, parentContext, newName, objName)};
}else{
// Leaf Node
return new Node[] {new JndiLeafNode(key, parentContext, newName, objName, np.getClassName())};
}
}catch (NamingException ne){
// Any of the context operations failed
// try to add at least Failed Node
return new Node[] {new JndiFailedNode(key, parentContext, newName, objName, np.getClassName())};
}
}
/** Heuristicaly decides whether specified class is a Context or not.
* @param className the name of Class
* @return true if className represents the name of Context*/
static boolean isContext(String className) {
if (className.equals(CONTEXT_CLASS_NAME)) {
return true;
} else if (isPrimitive(className)) {
return false;
} else {
try {
Class clazz = Class.forName(className);
if (getCtxClass().isAssignableFrom(clazz)) {
return true;
}
} catch (ClassNotFoundException e) {
// Changed from notifying an exception to return false
// Needed by some directory services, that provides an
// Class repository with deployment.
return false;
}
}
return false;
}
/** Decides if the string represents the name of primitive type
* @param s the name of type
* @return true iff s is one of int, long, char, boolean, float, byte, double
*/
private static boolean isPrimitive(String s) {
if (s.indexOf('.') >= 0) {
return false;
}
return s.equals("int") ||
s.equals("short") ||
s.equals("long") ||
s.equals("byte") ||
s.equals("char") ||
s.equals("float") ||
s.equals("double") ||
s.equals("boolean");
}
/** Returns the super class for classes representing the Context
* @return Class object for javax.naming.Context
*/
static Class getCtxClass() throws ClassNotFoundException {
if (ctxClass == null) {
ctxClass = Class.forName(CONTEXT_CLASS_NAME);
}
return ctxClass;
}
/** This method is called by Refreshd thread before performing
* main action
*/
public void preAction() throws Exception{
}
/** This is the main action called by Refreshd
*/
public void performAction() throws Exception{
NamingEnumeration ne = parentContext.list(offset);
this.keys.clear();
if (ne == null)
return;
int i=0;
while (ne.hasMore()){
this.keys.add(new JndiKey((NameClassPair)ne.next()));
i++;
}
}
/** This action is called by Refreshd after performing main action
*/
public void postAction() throws Exception{
JndiChildren.this.setKeys(this.keys);
}
/** public method that returns the node for which the Children is created
* @return Node
*/
public final Node getOwner(){
return this.getNode();
}
/** This method calls the refreshKey method of Children,
* used by Refreshd for changing the failed nodes
* @see org.netbeans.modules.jndi.utils.Refreshd
*/
public void updateKey(Object key){
this.refreshKey(key);
}
}
/*
* <<Log>>
* 13 Gandalf-post-FCS1.11.2.0 2/24/00 Ian Formanek Post FCS changes
* 12 Gandalf 1.11 1/14/00 Tomas Zezula
* 11 Gandalf 1.10 12/17/99 Tomas Zezula
* 10 Gandalf 1.9 12/15/99 Tomas Zezula
* 9 Gandalf 1.8 12/15/99 Tomas Zezula
* 8 Gandalf 1.7 11/5/99 Tomas Zezula
* 7 Gandalf 1.6 10/23/99 Ian Formanek NO SEMANTIC CHANGE - Sun
* Microsystems Copyright in File Comment
* 6 Gandalf 1.5 7/9/99 Ales Novak localization + code
* requirements followed
* 5 Gandalf 1.4 6/18/99 Ales Novak redesigned + delete
* action
* 4 Gandalf 1.3 6/9/99 Ales Novak refresh action +
* destroying subcontexts
* 3 Gandalf 1.2 6/9/99 Ian Formanek ---- Package Change To
* org.openide ----
* 2 Gandalf 1.1 6/8/99 Ales Novak sources beautified +
* subcontext creation
* 1 Gandalf 1.0 6/4/99 Ales Novak
* $
*/